#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "semantic_analyzer.h"

// 创建语义分析错误结果
// 参数：
// - message: 错误信息
// - line: 错误行号
// - column: 错误列号
// 返回值：包含错误信息的语义分析结果
static SemanticResult create_error_result(const char* message, int line, int column) {
    SemanticResult result;
    result.success = 0;
    result.error_message = strdup(message);
    result.error_line = line;
    result.error_column = column;
    return result;
}

// 创建语义分析成功结果
// 返回值：表示成功的语义分析结果
static SemanticResult create_success_result() {
    SemanticResult result;
    result.success = 1;
    result.error_message = NULL;
    result.error_line = 0;
    result.error_column = 0;
    return result;
}

// 分析CREATE TABLE语句的语义
// 参数：
// - node: CREATE TABLE语句的AST节点
// - catalog: 模式目录指针
// 返回值：语义分析结果
static SemanticResult analyze_create_table(ASTNode* node, Catalog* catalog) {
    CreateTableStmt* stmt = (CreateTableStmt*)node->extra_data;
    
    // 检查表是否已存在
    if (find_table_in_catalog(catalog, stmt->table_name)) {
        char error_msg[256];
        sprintf(error_msg, "Table '%s' already exists", stmt->table_name);
        return create_error_result(error_msg, node->token.line, node->token.column);
    }
    
    // 检查列名是否重复
    for (int i = 0; i < stmt->column_count; i++) {
        for (int j = i + 1; j < stmt->column_count; j++) {
            if (strcmp(stmt->columns[i].name, stmt->columns[j].name) == 0) {
                char error_msg[256];
                sprintf(error_msg, "Duplicate column name '%s'", stmt->columns[i].name);
                return create_error_result(error_msg, node->token.line, node->token.column);
            }
        }
    }
    
    // 检查VARCHAR类型是否有长度
    for (int i = 0; i < stmt->column_count; i++) {
        if (stmt->columns[i].type == TYPE_VARCHAR && stmt->columns[i].length <= 0) {
            char error_msg[256];
            sprintf(error_msg, "VARCHAR column '%s' requires a positive length", stmt->columns[i].name);
            return create_error_result(error_msg, node->token.line, node->token.column);
        }
    }
    
    return create_success_result();
}

SemanticResult check_expression_columns(ASTNode* expr, TableSchema* table, int line, int column) {
    if (!expr || !table) {
        return create_error_result("Invalid expression or table", line, column);
    }

    switch (expr->type) {
        case NODE_IDENTIFIER:
            // 对于标识符节点（列名），检查列是否存在
            {
                const char* col_name = expr->token.lexeme;
                if (!col_name || strlen(col_name) == 0) {
                    char error_msg[256];
                    sprintf(error_msg, "Column name cannot be empty in table '%s'", table->table_name);
                    return create_error_result(error_msg, line, column);
                }
                if (!find_column_in_table(table, col_name)) {
                    char error_msg[256];
                    sprintf(error_msg, "Column '%s' does not exist in table '%s'", 
                            col_name, table->table_name);
                    return create_error_result(error_msg, line, column);
                }
            }
            break;
        case NODE_VALUE:
            // 对于值节点，不需要检查列存在性，直接返回成功
            return create_success_result();
        case NODE_EXPRESSION:
            // 对于表达式节点，递归检查其子节点
            if (expr->left) {
                SemanticResult left_result = check_expression_columns(expr->left, table, line, column);
                if (!left_result.success) {
                    return left_result;
                }
            }
            if (expr->right) {
                SemanticResult right_result = check_expression_columns(expr->right, table, line, column);
                if (!right_result.success) {
                    return right_result;
                }
            }
            break;
        case NODE_BINARY_OP:
            // 递归检查左右子表达式
            ;
            SemanticResult left_result = check_expression_columns(expr->left, table, line, column);
            if (!left_result.success) {
                return left_result;
            }
            SemanticResult right_result = check_expression_columns(expr->right, table, line, column);
            if (!right_result.success) {
                return right_result;
            }
            break;
        case NODE_COLUMN_DEFINITION:
            // 对于列定义节点，检查列类型的有效性
            {
                ColumnDefinition* col_def = (ColumnDefinition*)expr->extra_data;
                if (col_def->type == TYPE_VARCHAR && col_def->length <= 0) {
                    char error_msg[256];
                    sprintf(error_msg, "VARCHAR column '%s' requires a positive length", col_def->name);
                    return create_error_result(error_msg, line, column);
                }
            }
            break;
        case NODE_CREATE_TABLE:
            // CREATE TABLE语句中的表达式检查
            {
                CreateTableStmt* stmt = (CreateTableStmt*)expr->extra_data;
                // 检查是否有重复的列名
                for (int i = 0; i < stmt->column_count; i++) {
                    for (int j = i + 1; j < stmt->column_count; j++) {
                        if (strcmp(stmt->columns[i].name, stmt->columns[j].name) == 0) {
                            char error_msg[256];
                            sprintf(error_msg, "Duplicate column name '%s'", stmt->columns[i].name);
                            return create_error_result(error_msg, line, column);
                        }
                    }
                }
            }
            break;
        case NODE_INSERT:
            // INSERT语句中的表达式检查
            {
                InsertStmt* stmt = (InsertStmt*)expr->extra_data;
                // 确保插入的列名存在
                for (int i = 0; i < stmt->column_count; i++) {
                    if (!find_column_in_table(table, stmt->columns[i])) {
                        char error_msg[256];
                        sprintf(error_msg, "Column '%s' does not exist in table '%s'", 
                                stmt->columns[i], stmt->table_name);
                        return create_error_result(error_msg, line, column);
                    }
                    // 检查插入值的表达式
                    if (stmt->values[i]) {
                        SemanticResult value_check = check_expression_columns(stmt->values[i], table, line, column);
                        if (!value_check.success) {
                            return value_check;
                        }
                    }
                }
            }
            break;
        case NODE_SELECT:
            // SELECT语句中的表达式检查
            {
                SelectStmt* stmt = (SelectStmt*)expr->extra_data;
                // 检查SELECT列表中的表达式
                for (int i = 0; i < stmt->column_count; i++) {
                    SemanticResult col_check = check_expression_columns(stmt->columns[i], table, line, column);
                    if (!col_check.success) {
                        return col_check;
                    }
                }
                // 检查WHERE子句中的表达式
                if (stmt->where_clause) {
                    SemanticResult where_check = check_expression_columns(stmt->where_clause, table, line, column);
                    if (!where_check.success) {
                        return where_check;
                    }
                }
            }
            break;
        case NODE_DELETE:
            // DELETE语句中的表达式检查
            {
                DeleteStmt* stmt = (DeleteStmt*)expr->extra_data;
                // 检查WHERE子句中的表达式
                if (stmt->where_clause) {
                    SemanticResult where_check = check_expression_columns(stmt->where_clause, table, line, column);
                    if (!where_check.success) {
                        return where_check;
                    }
                }
            }
            break;
        case NODE_DROP_TABLE:
            // DROP TABLE语句中的表达式检查
            // 检查表名是否有效
            {
                DropTableStmt* stmt = (DropTableStmt*)expr->extra_data;
                if (strlen(stmt->table_name) == 0) {
                    char error_msg[256];
                    sprintf(error_msg, "Table name cannot be empty");
                    return create_error_result(error_msg, line, column);
                }
            }
            break;
        case NODE_ALTER_TABLE:
            // ALTER TABLE语句中的表达式检查
            {
                AlterTableStmt* stmt = (AlterTableStmt*)expr->extra_data;
                // 检查操作的有效性
                if (stmt->action < ALTER_ADD_COLUMN || stmt->action > ALTER_MODIFY_COLUMN) {
                    char error_msg[256];
                    sprintf(error_msg, "Invalid ALTER TABLE action");
                    return create_error_result(error_msg, line, column);
                }
            }
            break;
        case NODE_UPDATE:
            // UPDATE语句中的表达式检查
            {
                UpdateStmt* stmt = (UpdateStmt*)expr->extra_data;
                // 检查SET子句中的列名和表达式
                for (int i = 0; i < stmt->set_count; i++) {
                    if (!find_column_in_table(table, stmt->column_names[i])) {
                        char error_msg[256];
                        sprintf(error_msg, "Column '%s' does not exist in table '%s'", 
                                stmt->column_names[i], stmt->table_name);
                        return create_error_result(error_msg, line, column);
                    }
                    // 检查赋值表达式 - 使用正确的字段名values
                    if (stmt->values[i]) {
                        SemanticResult expr_check = check_expression_columns(stmt->values[i], table, line, column);
                        if (!expr_check.success) {
                            return expr_check;
                        }
                    }
                }
                // 检查WHERE子句中的表达式
                if (stmt->where_clause) {
                    SemanticResult where_check = check_expression_columns(stmt->where_clause, table, line, column);
                    if (!where_check.success) {
                        return where_check;
                    }
                }
            }
            break;
    }
    
    return create_success_result();
}

// 修改analyze_select函数，处理SELECT *通配符的情况
static SemanticResult analyze_select(ASTNode* node, Catalog* catalog) {
    SelectStmt* stmt = (SelectStmt*)node->extra_data;
    
    // 检查表是否存在
    TableSchema* table = find_table_in_catalog(catalog, stmt->table_name);
    if (!table) {
        char error_msg[256];
        sprintf(error_msg, "Table '%s' does not exist", stmt->table_name);
        return create_error_result(error_msg, node->token.line, node->token.column);
    }
    
    // 检查是否有通配符*
    for (int i = 0; i < stmt->column_count; i++) {
        if (stmt->columns[i]->type == NODE_IDENTIFIER && 
            strcmp(stmt->columns[i]->token.lexeme, "*") == 0) {
            // 如果有通配符*，将其替换为表中的所有列
            ASTNode** old_columns = stmt->columns;
            int old_count = stmt->column_count;
            
            // 计算新的列数量（减去通配符，加上表中所有列）
            int new_count = old_count - 1 + table->ncols;
            stmt->columns = (ASTNode**)malloc(new_count * sizeof(ASTNode*));
            
            int new_index = 0;
            for (int j = 0; j < old_count; j++) {
                if (j == i) {
                    // 替换通配符*为表中的所有列
                    for (int k = 0; k < table->ncols; k++) {
                        stmt->columns[new_index] = create_ast_node(NODE_IDENTIFIER, 
                            (Token){.lexeme = strdup(table->cols[k].name), 
                                    .line = node->token.line, 
                                    .column = node->token.column});
                        new_index++;
                    }
                } else {
                    // 保留其他列
                    stmt->columns[new_index] = old_columns[j];
                    new_index++;
                }
            }
            
            stmt->column_count = new_count;
            free(old_columns[i]);  // 释放通配符节点
            free(old_columns);     // 释放旧的列数组
            
            break;  // 只处理第一个通配符*
        }
    }
    
    // 检查SELECT列表中的列是否存在
    for (int i = 0; i < stmt->column_count; i++) {
        SemanticResult column_check = check_expression_columns(stmt->columns[i], table, node->token.line, node->token.column);
        if (!column_check.success) {
            return column_check;
        }
    }
    
    // 检查WHERE子句中的列是否存在
    if (stmt->where_clause) {
        SemanticResult where_check = check_expression_columns(stmt->where_clause, table, node->token.line, node->token.column);
        if (!where_check.success) {
            return where_check;
        }
    }
    
    return create_success_result();
}

// 辅助函数获取列类型
static ColumnType get_column_type(TableSchema* table, const char* column_name) {
    if (!table || !column_name) {
        return TYPE_INT; // 默认返回
    }
    
    for (int i = 0; i < table->ncols; i++) {
        if (table->cols[i].name && strcmp(table->cols[i].name, column_name) == 0) {
            return table->cols[i].type;
        }
    }
    return TYPE_INT; // 默认返回
}

// 检查值的类型是否与列类型匹配
static SemanticResult check_value_type(TableSchema* table, const char* column_name, Token value, int line, int column) {
    ColumnType column_type = get_column_type(table, column_name);
    TokenType value_token_type = value.type;
    
    // 修复类型检查逻辑 - 确保数值类型接受NUMBER，字符串类型接受STRING
    switch (column_type) {
        case TYPE_INT:
        case TYPE_FLOAT:
        case TYPE_DOUBLE:
            // 数值类型应该接受NUMBER token
            if (value_token_type != NUMBER) {
                char error_msg[256];
                sprintf(error_msg, "Type mismatch for column '%s': expected numeric value", column_name);
                return create_error_result(error_msg, line, column);
            }
            break;
        case TYPE_VARCHAR:
            // 字符串类型应该接受STRING token
            if (value_token_type != STRING) {
                char error_msg[256];
                sprintf(error_msg, "Type mismatch for column '%s': expected string value", column_name);
                return create_error_result(error_msg, line, column);
            }
            break;
    }
    
    return create_success_result();
}

// 分析INSERT语句的语义
static SemanticResult analyze_insert(ASTNode* node, Catalog* catalog) {
    InsertStmt* stmt = (InsertStmt*)node->extra_data;
    
    // 检查表是否存在
    TableSchema* table = find_table_in_catalog(catalog, stmt->table_name);
    if (!table) {
        char error_msg[256];
        sprintf(error_msg, "Table '%s' does not exist", stmt->table_name);
        return create_error_result(error_msg, node->token.line, node->token.column);
    }
    
    // 检查列名是否存在（如果指定了列名）
    if (stmt->column_count > 0) {
        for (int i = 0; i < stmt->column_count; i++) {
            const char* column_name = stmt->columns[i];
            
            // 检查列是否存在
            if (!find_column_in_table(table, column_name)) {
                char error_msg[256];
                sprintf(error_msg, "Column '%s' does not exist in table '%s'", 
                        stmt->columns[i], stmt->table_name);
                return create_error_result(error_msg, node->token.line, node->token.column);
            }
            
            // 修复：正确调用check_value_type函数，参数顺序正确
            SemanticResult type_check = check_value_type(table, column_name, 
                                                        stmt->values[i]->token, node->token.line, node->token.column);
            if (!type_check.success) {
                return type_check;
            }
        }
        
        // 检查列数与值数是否匹配
        if (stmt->column_count != stmt->value_count) {
            char error_msg[256];
            sprintf(error_msg, "Column count (%d) doesn't match value count (%d)", 
                    stmt->column_count, stmt->value_count);
            return create_error_result(error_msg, node->token.line, node->token.column);
        }
    } else {
        // 如果没有指定列名，假设是插入所有列
        // 检查值的数量是否等于表的列数
        if (stmt->value_count != table->ncols) {
            char error_msg[256];
            sprintf(error_msg, "Value count (%d) doesn't match table column count (%d)", 
                    stmt->value_count, table->ncols);
            return create_error_result(error_msg, node->token.line, node->token.column);
        }
        
        // 对每个值进行类型检查，使用表的列名和类型
        for (int i = 0; i < stmt->value_count; i++) {
            const char* column_name = table->cols[i].name;
            SemanticResult type_check = check_value_type(table, column_name, 
                                                        stmt->values[i]->token, node->token.line, node->token.column);
            if (!type_check.success) {
                return type_check;
            }
        }
    }
    
    return create_success_result();
}

// 分析DELETE语句的语义
static SemanticResult analyze_delete(ASTNode* node, Catalog* catalog) {
    DeleteStmt* stmt = (DeleteStmt*)node->extra_data;
    
    // 检查表是否存在
    TableSchema* table = find_table_in_catalog(catalog, stmt->table_name);
    if (!table) {
        char error_msg[256];
        sprintf(error_msg, "Table '%s' does not exist", stmt->table_name);
        return create_error_result(error_msg, node->token.line, node->token.column);
    }
    
    // 检查WHERE子句中的列是否存在
    if (stmt->where_clause) {
        SemanticResult where_check = check_expression_columns(stmt->where_clause, table, node->token.line, node->token.column);
        if (!where_check.success) {
            return where_check;
        }
    }
    
    return create_success_result();
}

// 执行语义分析
SemanticResult analyze_semantics(ASTNode* node, Catalog* catalog) {
    SemanticResult result = {.success = 1}; // 使用1替代true
    
    if (!node) {
        result.success = 0; // 使用0替代false
        result.error_message = "NULL AST node";
        return result;
    }
    
    switch (node->type) {
        case NODE_CREATE_TABLE:
            return analyze_create_table(node, catalog);
        case NODE_INSERT:
            return analyze_insert(node, catalog);
        case NODE_SELECT:
            return analyze_select(node, catalog);
        case NODE_DELETE:
            return analyze_delete(node, catalog);
        case NODE_DROP_TABLE:
        case NODE_ALTER_TABLE:
        case NODE_UPDATE:
            if (node->type == NODE_DROP_TABLE) {
                DropTableStmt* stmt = (DropTableStmt*)node->extra_data;
                if (!find_table_in_catalog(catalog, stmt->table_name)) {
                    char error_msg[256];
                    sprintf(error_msg, "Table '%s' does not exist", stmt->table_name);
                    return create_error_result(error_msg, node->token.line, node->token.column);
                }
            } else if (node->type == NODE_ALTER_TABLE) {
                AlterTableStmt* stmt = (AlterTableStmt*)node->extra_data;
                if (!find_table_in_catalog(catalog, stmt->table_name)) {
                    char error_msg[256];
                    sprintf(error_msg, "Table '%s' does not exist", stmt->table_name);
                    return create_error_result(error_msg, node->token.line, node->token.column);
                }
            } else if (node->type == NODE_UPDATE) {
                UpdateStmt* stmt = (UpdateStmt*)node->extra_data;
                TableSchema* table = find_table_in_catalog(catalog, stmt->table_name);
                if (!table) {
                    char error_msg[256];
                    sprintf(error_msg, "Table '%s' does not exist", stmt->table_name);
                    return create_error_result(error_msg, node->token.line, node->token.column);
                }
                // 检查SET子句中的列是否存在
                for (int i = 0; i < stmt->set_count; i++) {
                    if (!find_column_in_table(table, stmt->column_names[i])) {
                        char error_msg[256];
                        sprintf(error_msg, "Column '%s' does not exist in table '%s'", 
                                stmt->column_names[i], stmt->table_name);
                        return create_error_result(error_msg, node->token.line, node->token.column);
                    }
                }
                // 检查WHERE子句中的列是否存在
                if (stmt->where_clause) {
                    SemanticResult where_check = check_expression_columns(stmt->where_clause, table, node->token.line, node->token.column);
                    if (!where_check.success) {
                        return where_check;
                    }
                }
            }
            return create_success_result();
        default:
            return create_error_result("Unknown AST node type", node->token.line, node->token.column); // 使用node替代ast
    }
}

// 释放语义分析结果
void free_semantic_result(SemanticResult result) {
    if (result.error_message) {
        free(result.error_message);
    }
}